﻿using Magic.Oidc.AuthorizatonServer.Extensions;
using Microsoft.EntityFrameworkCore;
using OpenIddict.Abstractions;
using static OpenIddict.Abstractions.OpenIddictConstants;

namespace Magic.Oidc.AuthorizatonServer
{
    public class ClientsSeeder
    {
        private readonly IServiceProvider _serviceProvider;

        public ClientsSeeder(IServiceProvider serviceProvider)
        {
            _serviceProvider = serviceProvider;
        }

        public async Task AddScopes()
        {

            await using var scope = _serviceProvider.CreateAsyncScope();
            var manager = scope.ServiceProvider.GetRequiredService<IOpenIddictScopeManager>();
            var apiScope = await manager.FindByNameAsync("api1");

            if (apiScope != null)
            {
                await manager.DeleteAsync(apiScope);
            }

            await manager.CreateAsync(new OpenIddictScopeDescriptor
            {
                DisplayName = "Api scope",
                Name = "api1",
                Resources =
            {
               "resource_server_1"
            }
            });
        }

        public async Task AddClients()
        {

            await using var scope = _serviceProvider.CreateAsyncScope();
            var context = scope.ServiceProvider.GetRequiredService<ApplicationDbContext>();

            await context.Database.EnsureCreatedAsync();

            var manager = scope.ServiceProvider.GetRequiredService<IOpenIddictApplicationManager>();
            var client = await manager.FindByClientIdAsync("web-client");

            if (client != null)
            {
                await manager.DeleteAsync(client);
            }

            await manager.CreateAsync(new OpenIddictApplicationDescriptor
            {
                ClientId = "web-client",
                ClientSecret = "901564A5-E7FE-42CB-B10D-61EF6A8F3654",
                ConsentType = ConsentTypes.Explicit,
                DisplayName = "Postman client application",
                RedirectUris =
            {
               new Uri("https://localhost:7002/swagger/oauth2-redirect.html")
            },
                PostLogoutRedirectUris =
            {
               new Uri("https://localhost:7002/resources")
            },
                Permissions =
            {
               Permissions.Endpoints.Authorization,
               Permissions.Endpoints.Logout,
               Permissions.Endpoints.Token,
               Permissions.GrantTypes.AuthorizationCode,
               Permissions.ResponseTypes.Code,
               Permissions.Scopes.Email,
               Permissions.Scopes.Profile,
               Permissions.Scopes.Roles,
               $"{Permissions.Prefixes.Scope}api1"
            },
                //Requirements =
                //{
                //    Requirements.Features.ProofKeyForCodeExchange
                //}
            });
        }

        public async Task AddOidcDebuggerClient()
        {
            await using var scope = _serviceProvider.CreateAsyncScope();

            var context = scope.ServiceProvider.GetRequiredService<ApplicationDbContext>();
            await context.Database.EnsureCreatedAsync();

            var manager = scope.ServiceProvider.GetRequiredService<IOpenIddictApplicationManager>();

            var client = await manager.FindByClientIdAsync("oidc-debugger");
            if (client != null)
            {
                await manager.DeleteAsync(client);
            }

            await manager.CreateAsync(new OpenIddictApplicationDescriptor
            {
                ClientId = "oidc-debugger",
                ClientSecret = "901564A5-E7FE-42CB-B10D-61EF6A8F3654",
                ConsentType = ConsentTypes.Explicit,
                DisplayName = "Postman client application",
                RedirectUris =
         {
            new Uri("https://oidcdebugger.com/debug")
         },
                PostLogoutRedirectUris =
         {
            new Uri("https://oauth.pstmn.io/v1/callback")
         },
                Permissions =
         {
            Permissions.Endpoints.Authorization,
            Permissions.Endpoints.Logout,
            Permissions.Endpoints.Token,
            Permissions.GrantTypes.AuthorizationCode,
            Permissions.ResponseTypes.Code,
            Permissions.Scopes.Email,
            Permissions.Scopes.Profile,
            Permissions.Scopes.Roles,
            $"{Permissions.Prefixes.Scope}api1"
         },
                //Requirements =
                //{
                //    Requirements.Features.ProofKeyForCodeExchange
                //}
            });
        }

        public async Task AddMvcClient()
        {
            await using var scope = _serviceProvider.CreateAsyncScope();
            var context = scope.ServiceProvider.GetRequiredService<ApplicationDbContext>();

            await context.Database.EnsureCreatedAsync();

            var manager = scope.ServiceProvider.GetRequiredService<IOpenIddictApplicationManager>();
            var client = await manager.FindByClientIdAsync("mvc");

            if (client != null)
            {
                await manager.DeleteAsync(client);
            }

            await manager.CreateAsync(new OpenIddictApplicationDescriptor
            {
                ClientId = "mvc",
                ClientSecret = "901564A5-E7FE-42CB-B10D-61EF6A8F3654",
                ConsentType = ConsentTypes.Explicit,
                DisplayName = "mvc client application",
                RedirectUris =
            {
               new Uri("https://localhost:7003/callback/login/local")
            },
                PostLogoutRedirectUris =
            {
               new Uri("https://localhost:7003/callback/logout/local")
            },
                Permissions =
            {
               Permissions.Endpoints.Authorization,
               Permissions.Endpoints.Logout,
               Permissions.Endpoints.Token,
               Permissions.GrantTypes.AuthorizationCode,
               Permissions.ResponseTypes.Code,
               Permissions.Scopes.Email,
               Permissions.Scopes.Profile,
               Permissions.Scopes.Roles,
               //$"{Permissions.Prefixes.Scope}api1"
            },
                Requirements =
                {
                    Requirements.Features.ProofKeyForCodeExchange
                }
            });
        }

        public async Task AddInitUsers()
        {
            var db = new ApplicationDbContext();
            
            if(db.Users.Count() == 0)
            {
                
                await db.Users.AddAsync(new Models.User()
                {
                    UserName = "test1",
                    Password = PasswordHasher.HashPassword("123456"),
                    Email="wtlemon@126.com",
                    Mobile = "110",
                    Remark="初始化测试账号",
                    //CreatedAt = 
                });
                await db.Users.AddAsync(new Models.User()
                {
                    UserName = "test2",
                    Password = PasswordHasher.HashPassword("123456"),
                    Email = "wtlemon@126.com",
                    Mobile = "110",
                    Remark = "初始化测试账号"
                });
                await db.SaveChangesAsync();
            }
        }
    }
}
